package com.knowno.customer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


import okhttp3.*;


import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

public class XfSparkStreamClient {

    public static final String hostUrl = "https://spark-api.xf-yun.com/v3.1/chat";
    public static final String appid = "";
    public static final String apiSecret = "";
    public static final String apiKey = "";

    /**
     * 发送消息
     *
     * @param uid     每个用户的id，用于区分不同用户
     * @param question 发送给大模型的消息
     * @return 获取websocket连接，以便于我们在获取完整大模型回复后手动关闭连接
     * @throws Exception
     */
    public static WebSocket sendMsg(String uid, String question, WebSocketListener listener) throws Exception {
        // 获取鉴权url
        String authUrl = getAuthUrl(hostUrl, apiKey, apiSecret);
        // 鉴权方法生成失败，直接返回 null
        if (authUrl == null) {
            return null;
        }
        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        // 将 https/http 连接替换为 ws/wss 连接
        String url = authUrl.replace("http://", "ws://").replace("https://", "wss://");
        Request request = new Request.Builder().url(url).build();
        // 建立 wss 连接
        WebSocket webSocket = okHttpClient.newWebSocket(request, listener);

        JSONObject requestJson=new JSONObject();

        JSONObject header=new JSONObject();  // header参数
        header.put("app_id",appid);
        header.put("uid",UUID.randomUUID().toString().substring(0, 10));

        JSONObject parameter=new JSONObject(); // parameter参数
        JSONObject chat=new JSONObject();
        chat.put("domain","generalv3"); //用的是3.0版本，记得改lv3
        chat.put("temperature",0.5);
        chat.put("max_tokens",4096);
        parameter.put("chat",chat);



        JSONObject payload=new JSONObject(); // payload参数
        JSONObject message=new JSONObject();
        JSONArray text=new JSONArray();

        // 最新问题
        JsonParse.RoleContent roleContent=new JsonParse.RoleContent();
        roleContent.role="user";
        roleContent.content=question;
        text.add(JSON.toJSON(roleContent));


        message.put("text",text);
        payload.put("message",message);

        requestJson.put("header",header);
        requestJson.put("parameter",parameter);
        requestJson.put("payload",payload);
        // 发送请求
        webSocket.send(requestJson.toString());
        return webSocket;
    }

    // 鉴权方法 copy
    public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
        URL url = new URL(hostUrl);
        // 时间
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());
        // 拼接
        String preStr = "host: " + url.getHost() + "\n" + "date: " + date + "\n" + "GET " + url.getPath() + " HTTP/1.1";
        // System.err.println(preStr);
        // SHA256加密
        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
        mac.init(spec);

        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // System.err.println(sha);
        // 拼接
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",
                apiKey, "hmac-sha256", "host date request-line", sha);
        // 拼接地址
        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder()
                .//
                        addQueryParameter("authorization",
                        Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8)))
                .//
                        addQueryParameter("date", date).//
                        addQueryParameter("host", url.getHost()).//
                        build();

        // System.err.println(httpUrl.toString());
        return httpUrl.toString();
    }


}
